'''
Created on 06-Jul-2009

@author: dexen
'''
import sys
import time
import unittest

from sqlalchemy import exc
    
from dexen.system.client import frontend, rpc_api
from dexen.system import constants

class Const:
    SCHEMA_NAME = "packing_boxes_v1"
    POP_NAME = "pop1"
    FUNC_NAME = "startup_synch"
    URL = "localhost"
    
class SchemaTest(unittest.TestCase):

    def setUp(self):
        pass
        #print "\n"

    def tearDown(self):
        frontend.reset_all_databases()
        #print "\n******************************\n"

    def test_db_reset(self):
        frontend.connect_to_server("localhost")
        frontend.create_new_schema(schema_name=Const.SCHEMA_NAME, 
                                 schema_folder=Const.SCHEMA_NAME)
        frontend.create_new_schema(schema_name="cubes", 
                                 schema_folder="cubes")
        schema_names = frontend.get_schema_names()
        print schema_names
        self.assert_(len(schema_names) == 2)
        frontend.reset_all_databases()
        schema_names = frontend.get_schema_names()
        self.assert_(len(schema_names) == 0)


    def test_schema_creation(self):
        frontend.connect_to_server("localhost")
        frontend.create_new_schema("packing_boxes_v2", Const.SCHEMA_NAME)
        schema_names = frontend.get_schema_names()
        """ Assertions """
        self.assert_(len(schema_names) == 1)
        self.assert_(schema_names[0] == "packing_boxes_v2")
                     
    def test_duplicate_schema(self):
        frontend.connect_to_server(Const.URL)
        frontend.create_new_schema(Const.SCHEMA_NAME, Const.SCHEMA_NAME)
        self.failUnlessRaises(exc.IntegrityError, frontend.create_new_schema,
                              Const.SCHEMA_NAME, Const.SCHEMA_NAME)

    def test_nonduplicate_schema(self):
        frontend.connect_to_server(Const.URL)
        frontend.create_new_schema(Const.SCHEMA_NAME, Const.SCHEMA_NAME)
        try:
            frontend.create_new_schema("pb2", Const.SCHEMA_NAME)
        except exc.IntegrityError:
            self.fail("Integrity exception should not occur!")
        except:
            self.fail("Unexpected exception!")

class PopulationTest(unittest.TestCase):
    def setUp(self):
        frontend.connect_to_server(Const.URL)
        frontend.create_new_schema(Const.SCHEMA_NAME, Const.SCHEMA_NAME)
        #print "\n"

    def tearDown(self):
        frontend.reset_all_databases()
        #print "\n******************************\n"    

    def test_run_config(self):
        try:
            frontend.run_config_function(Const.SCHEMA_NAME, 
                                         Const.POP_NAME,
                                         Const.FUNC_NAME)
            pop_names = frontend.get_population_names(Const.SCHEMA_NAME)
            self.assert_(len(pop_names) == 1)
            self.assert_(pop_names[0] == Const.POP_NAME)
            config_names = frontend.getConfigFunctionNames(
                           Const.SCHEMA_NAME)
            self.assert_(len(config_names) == 2)
            self.assert_(Const.FUNC_NAME in config_names)
            #self.assert_()
        except:
            print sys.exc_info()
            self.fail("Exception occured!")
    
class ScriptTest(unittest.TestCase):
    def setUp(self):
        frontend.connect_to_server(Const.URL)
        frontend.create_new_schema(Const.SCHEMA_NAME, Const.SCHEMA_NAME)
        frontend.run_config_function(Const.SCHEMA_NAME, Const.POP_NAME, 
                                     Const.FUNC_NAME)
        #print "\n"

    def tearDown(self):
        pass
        #frontend.reset_all_databases()
        
        #print "\n******************************\n"  

    def test_run_task(self):
        frontend.run_task(Const.SCHEMA_NAME, Const.POP_NAME, "initialization", 
                          constants.ONCE)
        frontend.run_task(Const.SCHEMA_NAME, Const.POP_NAME, "development", 
                          constants.LOOPED)
        frontend.run_task(Const.SCHEMA_NAME, Const.POP_NAME, "evaluation", 
                          constants.LOOPED)
        frontend.run_task(Const.SCHEMA_NAME, Const.POP_NAME, "feedback", 
                          constants.LOOPED)
        frontend.run_task(Const.SCHEMA_NAME, Const.POP_NAME, 
                          "flex_visualization", constants.LOOPED)
        time.sleep(100)
        frontend.stop_task(1)
        frontend.stop_task(2)
        frontend.stop_task(3)
        frontend.stop_task(4)

    def test_run_all_tasks(self):
        frontend.run_batch_tasks(Const.SCHEMA_NAME, Const.POP_NAME, "start_all")
        time.sleep(20)
        #TODO: implement stop all tasks in frontend
    
    def test_dynamic_task(self):
        frontend.run_task(Const.SCHEMA_NAME, Const.POP_NAME, 
                          "flex_visualization", constants.ONCE)
    
    def test_deneme(self):
        pass
    
   
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    #unittest.main()
    
    #server_suite = unittest.TestLoader().loadTestsFromTestCase(ServerTest)
    
    schema_suite = unittest.TestLoader().loadTestsFromTestCase(SchemaTest)
    pop_suite = unittest.TestLoader().loadTestsFromTestCase(PopulationTest)
    script_suite = unittest.TestLoader().loadTestsFromTestCase(ScriptTest)
    
    cur_suite = unittest.TestSuite()
    cur_suite.addTest(ScriptTest("test_run_task"))
    
    unittest.TextTestRunner(verbosity=3).run(cur_suite)
    #unittest.TextTestRunner(verbosity=3).run(schema_suite)
    #unittest.TextTestRunner(verbosity=3).run(pop_suite)
    #unittest.TextTestRunner(verbosity=3).run(script_suite)
    #unittest.TextTestRunner(verbosity=3).run(server_suite)
    
     